/**
 * 用户添加接口测试用例
 *
 * Created by snowingsea on 2020/01/31.
 */
const chai = require('chai');
const should = chai.should(); // eslint-disable-line no-unused-vars
chai.use(require('chai-http'));
const deepcopy = require('deepcopy');

const common = require('./../../common');
const Administrator = require('./../../../models/administrator');
const User = require('./../../../models/user');
const uri = require('./../uri');
const { roleKind, statusKind } = require('./../../../../phoenix/models/users');
// const license = require('./../../../../phoenix/models/license');

module.exports = describe('/POST users.json', function () {
  const url = '/users.json';
  const administrator = new Administrator();
  const newUserIds = [];
  after(function (done) {
    administrator.removeUsers(newUserIds)
      .then(() => {
        done();
      })
      .catch(done);
  });

  common.should.be.user(uri, url, 'post');
  common.should.be.administrator(uri, url, 'post');

  // 正常添加用户
  it('it should ADD a user successfully', function (done) {
    const userInfo = User.getRandomUserInfo();
    const sendData = deepcopy(userInfo);
    delete sendData.role;
    administrator.login()
      .then(() => {
        chai.request(uri)
          .post(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .send(sendData)
          .end((err, res) => {
            newUserIds.push(res.body.userId);
            const user = new User(userInfo.username);
            user.password = userInfo.password;
            user.login()
              .then(() => user.logout())
              .then(() => {
                res.should.have.status(200);
                common.should.be.userMessage(res.body);
                res.body.userId.should.be.eql(user.userId);
                res.body.status.should.be.eql(statusKind.unactivated);
                const actual = deepcopy(res.body);
                delete actual.userId;
                delete actual.status;
                const expected = deepcopy(userInfo);
                delete expected.password;
                delete expected.roles;
                actual.should.be.eql(expected);
                done();
              })
              .catch(done);
          });
      })
      .catch(done);
  });

  // 昵称缺省与用户名一致
  it('it should be same to username when nickname is empty', function (done) {
    const userInfo = User.getRandomUserInfo();
    const sendData = deepcopy(userInfo);
    delete sendData.role;
    delete sendData.nickname;
    administrator.login()
      .then(() => {
        chai.request(uri)
          .post(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .send(sendData)
          .end((err, res) => {
            newUserIds.push(res.body.userId);
            res.should.have.status(200);
            common.should.be.userMessage(res.body);
            res.body.nickname.should.be.eql(userInfo.username);
            done();
          });
      })
      .catch(done);
  });

  // 默认语言为中文
  it('it should be "zh-CN" when lang is empty', function (done) {
    const userInfo = User.getRandomUserInfo();
    const sendData = deepcopy(userInfo);
    delete sendData.role;
    delete sendData.lang;
    administrator.login()
      .then(() => {
        chai.request(uri)
          .post(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .send(sendData)
          .end((err, res) => {
            newUserIds.push(res.body.userId);
            res.should.have.status(200);
            common.should.be.userMessage(res.body);
            res.body.lang.should.be.eql('zh-CN');
            done();
          });
      })
      .catch(done);
  });

  // 重复添加
  it('it should fail to add user when the username is exists', function (done) {
    let newUser;
    administrator.createRandomTester()
      .then((user) => {
        newUserIds.push(user.userId);
        newUser = user;
        return administrator.login();
      })
      .then(() => {
        chai.request(uri)
          .post(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .send({
            username: newUser.username,
            password: newUser.password,
            roles: [],
          })
          .end((err, res) => {
            res.should.have.status(409);
            common.should.be.errorMessage(res.body);
            done();
          });
      })
      .catch(done);
  });

  // 不可添加超过上限
  /*
  it('it should fail to add user when the count reaches the limit', function (done) {
    administrator.login()
      .then(() => administrator.replaceLicense(license.statusKind.exceedTester))
      .then(() => {
        const userInfo = User.getRandomUserInfo();
        const sendData = deepcopy(userInfo);
        delete sendData.role;
        sendData.roles.push(roleKind.tester);
        chai.request(uri)
          .post(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .send(sendData)
          .end((err, res) => {
            administrator.replaceLicense(license.statusKind.normal)
              .then(() => {
                res.should.have.status(403);
                common.should.be.errorMessage(res.body);
                done();
              })
              .catch(done);
          });
      })
      .catch(done);
  });
   */

  // 不可添加超级用户
  it('it should fail to add super user', function (done) {
    administrator.login()
      .then(() => {
        const userInfo = User.getRandomUserInfo();
        const sendData = deepcopy(userInfo);
        delete sendData.role;
        sendData.roles.push(roleKind.superUser);
        chai.request(uri)
          .post(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .send(sendData)
          .end((err, res) => {
            res.should.have.status(416);
            common.should.be.errorMessage(res.body);
            done();
          });
      })
      .catch(done);
  });

  // 缺少参数
  const query = {
    username: User.getRandomUserInfo().username,
    password: User.getRandomUserInfo().password,
    roles: User.getRandomUserInfo().roles,
  };
  Object.keys(query).forEach((key) => {
    it(`it should deny invalid request of missing "${key}"`, function (done) {
      const invalidQuery = deepcopy(query);
      delete invalidQuery[key];
      administrator.login()
        .then(() => {
          chai.request(uri)
            .post(url)
            .set('Authorization', `Bearer ${administrator.token.accessToken}`)
            .send(invalidQuery)
            .end((err, res) => {
              res.should.have.status(400);
              common.should.be.errorMessage(res.body);
              done();
            });
        })
        .catch(done);
    });
  });
});
